home *** CD-ROM | disk | FTP | other *** search
- Subject: v19i087: Cnews production release, Part10/19
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: utzoo!henry
- Posting-number: Volume 19, Issue 87
- Archive-name: cnews2/part10
-
- : ---CUT HERE---
- echo 'libc/getdate.y':
- sed 's/^X//' >'libc/getdate.y' <<'!'
- X%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
- X%{
- X /* Steven M. Bellovin (unc!smb) */
- X /* Dept. of Computer Science */
- X /* University of North Carolina at Chapel Hill */
- X /* @(#)getdate.y 2.13 9/16/86 */
- X
- X#include <sys/types.h>
- X#include <sys/timeb.h>
- X#include <ctype.h>
- X#include <time.h>
- X
- X#define NULL 0
- X
- X#define daysec (24L*60L*60L)
- X
- X static int timeflag, zoneflag, dateflag, dayflag, relflag;
- X static time_t relsec, relmonth;
- X static int hh, mm, ss, merid, daylight;
- X static int dayord, dayreq;
- X static int month, day, year;
- X static int ourzone;
- X
- X#define AM 1
- X#define PM 2
- X#define DAYLIGHT 1
- X#define STANDARD 2
- X#define MAYBE 3
- X%}
- X
- X%%
- Xtimedate: /* empty */
- X | timedate item;
- X
- Xitem: tspec =
- X {timeflag++;}
- X | zone =
- X {zoneflag++;}
- X | dtspec =
- X {dateflag++;}
- X | dyspec =
- X {dayflag++;}
- X | rspec =
- X {relflag++;}
- X | nspec;
- X
- Xnspec: NUMBER =
- X {if (timeflag && dateflag && !relflag) year = $1;
- X else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
- X
- Xtspec: NUMBER MERIDIAN =
- X {hh = $1; mm = 0; ss = 0; merid = $2;}
- X | NUMBER ':' NUMBER =
- X {hh = $1; mm = $3; merid = 24;}
- X | NUMBER ':' NUMBER MERIDIAN =
- X {hh = $1; mm = $3; merid = $4;}
- X | NUMBER ':' NUMBER NUMBER =
- X {hh = $1; mm = $3; merid = 24;
- X daylight = STANDARD; ourzone = $4%100 + 60*$4/100;}
- X | NUMBER ':' NUMBER ':' NUMBER =
- X {hh = $1; mm = $3; ss = $5; merid = 24;}
- X | NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
- X {hh = $1; mm = $3; ss = $5; merid = $6;}
- X | NUMBER ':' NUMBER ':' NUMBER NUMBER =
- X {hh = $1; mm = $3; ss = $5; merid = 24;
- X daylight = STANDARD; ourzone = $6%100 + 60*$6/100;};
- X
- Xzone: ZONE =
- X {ourzone = $1; daylight = STANDARD;}
- X | DAYZONE =
- X {ourzone = $1; daylight = DAYLIGHT;};
- X
- Xdyspec: DAY =
- X {dayord = 1; dayreq = $1;}
- X | DAY ',' =
- X {dayord = 1; dayreq = $1;}
- X | NUMBER DAY =
- X {dayord = $1; dayreq = $2;};
- X
- Xdtspec: NUMBER '/' NUMBER =
- X {month = $1; day = $3;}
- X | NUMBER '/' NUMBER '/' NUMBER =
- X {month = $1; day = $3; year = $5;}
- X | MONTH NUMBER =
- X {month = $1; day = $2;}
- X | MONTH NUMBER ',' NUMBER =
- X {month = $1; day = $2; year = $4;}
- X | NUMBER MONTH =
- X {month = $2; day = $1;}
- X | NUMBER MONTH NUMBER =
- X {month = $2; day = $1; year = $3;};
- X
- X
- Xrspec: NUMBER UNIT =
- X {relsec += 60L * $1 * $2;}
- X | NUMBER MUNIT =
- X {relmonth += $1 * $2;}
- X | NUMBER SUNIT =
- X {relsec += $1;}
- X | UNIT =
- X {relsec += 60L * $1;}
- X | MUNIT =
- X {relmonth += $1;}
- X | SUNIT =
- X {relsec++;}
- X | rspec AGO =
- X {relsec = -relsec; relmonth = -relmonth;};
- X%%
- X
- Xstatic int mdays[12] =
- X {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- X#define epoch 1970
- X
- Xextern struct tm *localtime();
- Xtime_t dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
- Xint mm, dd, yy, h, m, s, mer, zone, dayflag;
- X{
- X time_t tod, jdate;
- X register int i;
- X time_t timeconv();
- X
- X if (yy < 0) yy = -yy;
- X if (yy < 100) yy += 1900;
- X mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
- X if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
- X dd < 1 || dd > mdays[--mm]) return (-1);
- X jdate = dd-1;
- X for (i=0; i<mm; i++) jdate += mdays[i];
- X for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
- X jdate *= daysec;
- X jdate += zone * 60L;
- X if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
- X jdate += tod;
- X if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
- X jdate += -1*60*60;
- X return (jdate);
- X}
- X
- Xtime_t dayconv(ord, day, now) int ord, day; time_t now;
- X{
- X register struct tm *loctime;
- X time_t tod;
- X time_t daylcorr();
- X
- X tod = now;
- X loctime = localtime(&tod);
- X tod += daysec * ((day - loctime->tm_wday + 7) % 7);
- X tod += 7*daysec*(ord<=0?ord:ord-1);
- X return daylcorr(tod, now);
- X}
- X
- Xtime_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer;
- X{
- X if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
- X switch (mer) {
- X case AM: if (hh < 1 || hh > 12) return(-1);
- X return (60L * ((hh%12)*60L + mm)+ss);
- X case PM: if (hh < 1 || hh > 12) return(-1);
- X return (60L * ((hh%12 +12)*60L + mm)+ss);
- X case 24: if (hh < 0 || hh > 23) return (-1);
- X return (60L * (hh*60L + mm)+ss);
- X default: return (-1);
- X }
- X}
- Xtime_t monthadd(sdate, relmonth) time_t sdate, relmonth;
- X{
- X struct tm *ltime;
- X time_t dateconv();
- X time_t daylcorr();
- X int mm, yy;
- X
- X if (relmonth == 0) return 0;
- X ltime = localtime(&sdate);
- X mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
- X yy = mm/12;
- X mm = mm%12 + 1;
- X return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
- X ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
- X}
- X
- Xtime_t daylcorr(future, now) time_t future, now;
- X{
- X int fdayl, nowdayl;
- X
- X nowdayl = (localtime(&now)->tm_hour+1) % 24;
- X fdayl = (localtime(&future)->tm_hour+1) % 24;
- X return (future-now) + 60L*60L*(nowdayl-fdayl);
- X}
- X
- Xstatic char *lptr;
- X
- Xyylex()
- X{
- X extern int yylval;
- X int sign;
- X register char c;
- X register char *p;
- X char idbuf[20];
- X int pcnt;
- X
- X for (;;) {
- X while (isspace(*lptr)) lptr++;
- X
- X if (isdigit(c = *lptr) || c == '-' || c == '+') {
- X if (c== '-' || c == '+') {
- X if (c=='-') sign = -1;
- X else sign = 1;
- X if (!isdigit(*++lptr)) {
- X /* yylval = sign; return (NUMBER); */
- X return yylex(); /* skip the '-' sign */
- X }
- X } else sign = 1;
- X yylval = 0;
- X while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
- X yylval *= sign;
- X lptr--;
- X return (NUMBER);
- X
- X } else if (isalpha(c)) {
- X p = idbuf;
- X while (isalpha(c = *lptr++) || c=='.')
- X if (p < &idbuf[sizeof(idbuf)-1])
- X *p++ = c;
- X *p = '\0';
- X lptr--;
- X return (lookup(idbuf));
- X }
- X
- X else if (c == '(') {
- X pcnt = 0;
- X do {
- X c = *lptr++;
- X if (c == '\0') return(c);
- X else if (c == '(') pcnt++;
- X else if (c == ')') pcnt--;
- X } while (pcnt > 0);
- X }
- X
- X else return (*lptr++);
- X }
- X}
- X
- Xstruct table {
- X char *name;
- X int type, value;
- X};
- X
- Xstruct table mdtab[] = {
- X {"January", MONTH, 1},
- X {"February", MONTH, 2},
- X {"March", MONTH, 3},
- X {"April", MONTH, 4},
- X {"May", MONTH, 5},
- X {"June", MONTH, 6},
- X {"July", MONTH, 7},
- X {"August", MONTH, 8},
- X {"September", MONTH, 9},
- X {"Sept", MONTH, 9},
- X {"October", MONTH, 10},
- X {"November", MONTH, 11},
- X {"December", MONTH, 12},
- X
- X {"Sunday", DAY, 0},
- X {"Monday", DAY, 1},
- X {"Tuesday", DAY, 2},
- X {"Tues", DAY, 2},
- X {"Wednesday", DAY, 3},
- X {"Wednes", DAY, 3},
- X {"Thursday", DAY, 4},
- X {"Thur", DAY, 4},
- X {"Thurs", DAY, 4},
- X {"Friday", DAY, 5},
- X {"Saturday", DAY, 6},
- X {0, 0, 0}};
- X
- X#define HRS *60
- X#define HALFHR 30
- Xstruct table mztab[] = {
- X {"a.m.", MERIDIAN, AM},
- X {"am", MERIDIAN, AM},
- X {"p.m.", MERIDIAN, PM},
- X {"pm", MERIDIAN, PM},
- X {"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */
- X {"n.s.t.", ZONE, 3 HRS + HALFHR},
- X {"ast", ZONE, 4 HRS}, /* Atlantic */
- X {"a.s.t.", ZONE, 4 HRS},
- X {"adt", DAYZONE, 4 HRS},
- X {"a.d.t.", DAYZONE, 4 HRS},
- X {"est", ZONE, 5 HRS}, /* Eastern */
- X {"e.s.t.", ZONE, 5 HRS},
- X {"edt", DAYZONE, 5 HRS},
- X {"e.d.t.", DAYZONE, 5 HRS},
- X {"cst", ZONE, 6 HRS}, /* Central */
- X {"c.s.t.", ZONE, 6 HRS},
- X {"cdt", DAYZONE, 6 HRS},
- X {"c.d.t.", DAYZONE, 6 HRS},
- X {"mst", ZONE, 7 HRS}, /* Mountain */
- X {"m.s.t.", ZONE, 7 HRS},
- X {"mdt", DAYZONE, 7 HRS},
- X {"m.d.t.", DAYZONE, 7 HRS},
- X {"pst", ZONE, 8 HRS}, /* Pacific */
- X {"p.s.t.", ZONE, 8 HRS},
- X {"pdt", DAYZONE, 8 HRS},
- X {"p.d.t.", DAYZONE, 8 HRS},
- X {"yst", ZONE, 9 HRS}, /* Yukon */
- X {"y.s.t.", ZONE, 9 HRS},
- X {"ydt", DAYZONE, 9 HRS},
- X {"y.d.t.", DAYZONE, 9 HRS},
- X {"hst", ZONE, 10 HRS}, /* Hawaii */
- X {"h.s.t.", ZONE, 10 HRS},
- X {"hdt", DAYZONE, 10 HRS},
- X {"h.d.t.", DAYZONE, 10 HRS},
- X
- X {"gmt", ZONE, 0 HRS},
- X {"g.m.t.", ZONE, 0 HRS},
- X {"bst", DAYZONE, 0 HRS}, /* British Summer Time */
- X {"b.s.t.", DAYZONE, 0 HRS},
- X {"eet", ZONE, 0 HRS}, /* European Eastern Time */
- X {"e.e.t.", ZONE, 0 HRS},
- X {"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */
- X {"e.e.s.t.", DAYZONE, 0 HRS},
- X {"met", ZONE, -1 HRS}, /* Middle European Time */
- X {"m.e.t.", ZONE, -1 HRS},
- X {"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */
- X {"m.e.s.t.", DAYZONE, -1 HRS},
- X {"wet", ZONE, -2 HRS }, /* Western European Time */
- X {"w.e.t.", ZONE, -2 HRS },
- X {"west", DAYZONE, -2 HRS}, /* Western European Summer Time */
- X {"w.e.s.t.", DAYZONE, -2 HRS},
- X
- X {"jst", ZONE, -9 HRS}, /* Japan Standard Time */
- X {"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */
- X /* No daylight savings time */
- X
- X {"aest", ZONE, -10 HRS}, /* Australian Eastern Time */
- X {"a.e.s.t.", ZONE, -10 HRS},
- X {"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */
- X {"a.e.s.s.t.", DAYZONE, -10 HRS},
- X {"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */
- X {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
- X {"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */
- X {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
- X {"awst", ZONE, -8 HRS}, /* Australian Western Time */
- X {"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */
- X {0, 0, 0}};
- X
- Xstruct table unittb[] = {
- X {"year", MUNIT, 12},
- X {"month", MUNIT, 1},
- X {"fortnight", UNIT, 14*24*60},
- X {"week", UNIT, 7*24*60},
- X {"day", UNIT, 1*24*60},
- X {"hour", UNIT, 60},
- X {"minute", UNIT, 1},
- X {"min", UNIT, 1},
- X {"second", SUNIT, 1},
- X {"sec", SUNIT, 1},
- X {0, 0, 0}};
- X
- Xstruct table othertb[] = {
- X {"tomorrow", UNIT, 1*24*60},
- X {"yesterday", UNIT, -1*24*60},
- X {"today", UNIT, 0},
- X {"now", UNIT, 0},
- X {"last", NUMBER, -1},
- X {"this", UNIT, 0},
- X {"next", NUMBER, 2},
- X {"first", NUMBER, 1},
- X /* {"second", NUMBER, 2}, */
- X {"third", NUMBER, 3},
- X {"fourth", NUMBER, 4},
- X {"fifth", NUMBER, 5},
- X {"sixth", NUMBER, 6},
- X {"seventh", NUMBER, 7},
- X {"eigth", NUMBER, 8},
- X {"ninth", NUMBER, 9},
- X {"tenth", NUMBER, 10},
- X {"eleventh", NUMBER, 11},
- X {"twelfth", NUMBER, 12},
- X {"ago", AGO, 1},
- X {0, 0, 0}};
- X
- Xstruct table milzone[] = {
- X {"a", ZONE, 1 HRS},
- X {"b", ZONE, 2 HRS},
- X {"c", ZONE, 3 HRS},
- X {"d", ZONE, 4 HRS},
- X {"e", ZONE, 5 HRS},
- X {"f", ZONE, 6 HRS},
- X {"g", ZONE, 7 HRS},
- X {"h", ZONE, 8 HRS},
- X {"i", ZONE, 9 HRS},
- X {"k", ZONE, 10 HRS},
- X {"l", ZONE, 11 HRS},
- X {"m", ZONE, 12 HRS},
- X {"n", ZONE, -1 HRS},
- X {"o", ZONE, -2 HRS},
- X {"p", ZONE, -3 HRS},
- X {"q", ZONE, -4 HRS},
- X {"r", ZONE, -5 HRS},
- X {"s", ZONE, -6 HRS},
- X {"t", ZONE, -7 HRS},
- X {"u", ZONE, -8 HRS},
- X {"v", ZONE, -9 HRS},
- X {"w", ZONE, -10 HRS},
- X {"x", ZONE, -11 HRS},
- X {"y", ZONE, -12 HRS},
- X {"z", ZONE, 0 HRS},
- X {0, 0, 0}};
- X
- Xlookup(id) char *id;
- X{
- X#define gotit (yylval=i->value, i->type)
- X#define getid for(j=idvar, k=id; *j++ = *k++; )
- X
- X char idvar[20];
- X register char *j, *k;
- X register struct table *i;
- X int abbrev;
- X
- X getid;
- X if (strlen(idvar) == 3) abbrev = 1;
- X else if (strlen(idvar) == 4 && idvar[3] == '.') {
- X abbrev = 1;
- X idvar[3] = '\0';
- X }
- X else abbrev = 0;
- X
- X if (islower(*idvar)) *idvar = toupper(*idvar);
- X
- X for (i = mdtab; i->name; i++) {
- X k = idvar;
- X for (j = i->name; *j++ == *k++;) {
- X if (abbrev && j==i->name+3) return gotit;
- X if (j[-1] == 0) return gotit;
- X }
- X }
- X
- X getid;
- X for (i = mztab; i->name; i++)
- X if (strcmp(i->name, idvar) == 0) return gotit;
- X
- X for (j = idvar; *j; j++)
- X if (isupper(*j)) *j = tolower(*j);
- X for (i=mztab; i->name; i++)
- X if (strcmp(i->name, idvar) == 0) return gotit;
- X
- X getid;
- X for (i=unittb; i->name; i++)
- X if (strcmp(i->name, idvar) == 0) return gotit;
- X
- X if (idvar[strlen(idvar)-1] == 's')
- X idvar[strlen(idvar)-1] = '\0';
- X for (i=unittb; i->name; i++)
- X if (strcmp(i->name, idvar) == 0) return gotit;
- X
- X getid;
- X for (i = othertb; i->name; i++)
- X if (strcmp(i->name, idvar) == 0) return gotit;
- X
- X getid;
- X if (strlen(idvar) == 1 && isalpha(*idvar)) {
- X if (isupper(*idvar)) *idvar = tolower(*idvar);
- X for (i = milzone; i->name; i++)
- X if (strcmp(i->name, idvar) == 0) return gotit;
- X }
- X
- X return(ID);
- X}
- X
- Xtime_t getdate(p, now) char *p; struct timeb *now;
- X{
- X#define mcheck(f) if (f>1) err++
- X time_t monthadd();
- X int err;
- X struct tm *lt;
- X struct timeb ftz;
- X
- X time_t sdate, tod;
- X
- X lptr = p;
- X if (now == ((struct timeb *) NULL)) {
- X now = &ftz;
- X ftime(&ftz);
- X }
- X lt = localtime(&now->time);
- X year = lt->tm_year;
- X month = lt->tm_mon+1;
- X day = lt->tm_mday;
- X relsec = 0; relmonth = 0;
- X timeflag=zoneflag=dateflag=dayflag=relflag=0;
- X ourzone = now->timezone;
- X daylight = MAYBE;
- X hh = mm = ss = 0;
- X merid = 24;
- X
- X if (err = yyparse()) return (-1);
- X
- X mcheck(timeflag);
- X mcheck(zoneflag);
- X mcheck(dateflag);
- X mcheck(dayflag);
- X
- X if (err) return (-1);
- X if (dateflag || timeflag || dayflag) {
- X sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight);
- X if (sdate < 0) return -1;
- X }
- X else {
- X sdate = now->time;
- X if (relflag == 0)
- X sdate -= (lt->tm_sec + lt->tm_min*60 +
- X lt->tm_hour*(60L*60L));
- X }
- X
- X sdate += relsec;
- X sdate += monthadd(sdate, relmonth);
- X
- X if (dayflag && !dateflag) {
- X tod = dayconv(dayord, dayreq, sdate);
- X sdate += tod;
- X }
- X
- X return sdate;
- X}
- X
- Xyyerror(s) char *s;
- X{}
- !
- echo 'libc/nfclose.c':
- sed 's/^X//' >'libc/nfclose.c' <<'!'
- X/*
- X * nfclose(stream) - flush the stream, fsync its file descriptor and
- X * fclose the stream, checking for errors at all stages. This dance
- X * is needed to work around the lack of Unix file system semantics
- X * in Sun's NFS. Returns EOF on error.
- X */
- X
- X#include <stdio.h>
- X
- Xint
- Xnfclose(stream)
- Xregister FILE *stream;
- X{
- X register int ret = 0;
- X
- X if (fflush(stream) == EOF)
- X ret = EOF;
- X if (fsync(fileno(stream)) < 0) /* may get delayed error here */
- X ret = EOF;
- X if (fclose(stream) == EOF)
- X ret = EOF;
- X return ret;
- X}
- !
- echo 'libcnews/config.c':
- sed 's/^X//' >'libcnews/config.c' <<'!'
- X/*
- X * news configuration inquiry
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "libc.h"
- X#include "news.h"
- X#include "config.h"
- X
- X#ifndef NULL
- X#define NULL 0
- X#endif
- X
- X#ifndef NEWSCTL
- X/* =()<#define NEWSCTL "@<NEWSCTL>@">()= */
- X#define NEWSCTL "/usr/lib/news"
- X#endif
- X#ifndef NEWSPATH
- X/* =()<#define NEWSPATH "@<NEWSPATH>@">()= */
- X#define NEWSPATH "/bin:/usr/bin"
- X#endif
- X#ifndef NEWSARTS
- X/* =()<#define NEWSARTS "@<NEWSARTS>@">()= */
- X#define NEWSARTS "/usr/spool/news"
- X#endif
- X#ifndef NEWSBIN
- X/* =()<#define NEWSBIN "@<NEWSBIN>@">()= */
- X#define NEWSBIN "/usr/lib/newsbin"
- X#endif
- X#ifndef NEWSUMASK
- X/* =()<#define NEWSUMASK @<NEWSUMASK>@>()= */
- X#define NEWSUMASK 002
- X#endif
- X#ifndef NEWSMASTER
- X/* =()<#define NEWSMASTER "@<NEWSMASTER>@">()= */
- X#define NEWSMASTER "usenet"
- X#endif
- X
- Xstatic char *pwd = NULL; /* Current directory, NULL means unknown. */
- Xstatic int dirsset = NO; /* Have the following been set up? */
- Xstatic char *arts = NEWSARTS;
- Xstatic char *bin = NEWSBIN;
- Xstatic char *ctl = NEWSCTL;
- Xstatic char *path = NEWSPATH;
- Xstatic int numask = NEWSUMASK;
- Xstatic char *nmaster = NEWSMASTER;
- X#define DIRS() if (!dirsset) setdirs()
- X
- Xextern char *strcpy();
- Xextern char *strcat();
- Xextern char *getenv();
- X
- X/*
- X - setdirs - set up stuff from environment, for use by other functions
- X *
- X * Invokes user-supplied function unprivileged() if non-standard values used.
- X */
- Xstatic void
- Xsetdirs()
- X{
- X register char *p;
- X register int nonstd = NO;
- X register int mask;
- X register char *scan;
- X
- X if (dirsset)
- X return;
- X
- X p = getenv("NEWSARTS");
- X if (p != NULL && !STREQ(p, arts)) {
- X nonstd = YES;
- X arts = p;
- X }
- X
- X p = getenv("NEWSCTL");
- X if (p != NULL && !STREQ(p, ctl)) {
- X ctl = p;
- X nonstd = YES;
- X }
- X
- X p = getenv("NEWSPATH");
- X if (p != NULL && !STREQ(p, path)) {
- X path = p;
- X nonstd = YES;
- X }
- X
- X p = getenv("NEWSBIN");
- X if (p != NULL && !STREQ(p, bin)) {
- X bin = p;
- X nonstd = YES;
- X }
- X
- X p = getenv("NEWSUMASK");
- X if (p != NULL) {
- X mask = 0;
- X for (scan = p; *scan != '\0'; scan++)
- X if ('0' <= *scan && *scan <= '7' && mask <= 077)
- X mask = (mask << 3) | (*scan - '0');
- X else { /* Garbage, ignore it. */
- X mask = numask;
- X break; /* NOTE BREAK OUT */
- X }
- X if (mask != numask) {
- X numask = mask;
- X nonstd = YES;
- X }
- X }
- X
- X p = getenv("NEWSMASTER");
- X if (p != NULL && !STREQ(p, nmaster)) {
- X nmaster = p;
- X nonstd = YES;
- X }
- X
- X dirsset = YES;
- X if (nonstd)
- X unprivileged();
- X}
- X
- X/*
- X - artfile - best pathname for a file in NEWSARTS
- X */
- Xchar *
- Xartfile(base)
- Xchar *base;
- X{
- X static char *artf = NULL;
- X
- X DIRS();
- X
- X if (base == NULL) /* he just wants the directory */
- X return (arts);
- X
- X if (artf != NULL)
- X free(artf); /* toss old returned value */
- X if (pwd != NULL && STREQ(pwd, arts))
- X artf = strsave(base);
- X else
- X artf = str3save(arts, SFNDELIM, base);
- X
- X return (artf);
- X}
- X
- X/*
- X - fullartfile - full pathname for a file in NEWSARTS
- X */
- Xchar *
- Xfullartfile(base)
- Xchar *base;
- X{
- X register char *p;
- X register char *pwdsave;
- X
- X pwdsave = pwd;
- X pwd = NULL; /* fool artfile() into giving full path */
- X p = artfile(base);
- X pwd = pwdsave;
- X return (p);
- X}
- X
- X/*
- X - ctlfile - full pathname for a file in NEWSCTL
- X */
- Xchar *
- Xctlfile(base)
- Xchar *base;
- X{
- X static char *ctlf = NULL;
- X
- X DIRS();
- X
- X if (ctlf != NULL)
- X free(ctlf); /* toss old returned value */
- X
- X if (base == NULL) {
- X ctlf = NULL;
- X return(ctl);
- X } else {
- X ctlf = str3save(ctl, SFNDELIM, base);
- X return(ctlf);
- X }
- X}
- X
- X/*
- X - binfile - full pathname for a file in NEWSBIN
- X */
- Xchar *
- Xbinfile(base)
- Xchar *base;
- X{
- X static char *binf = NULL;
- X
- X DIRS();
- X
- X if (binf != NULL)
- X free(binf); /* toss old returned value */
- X
- X if (base == NULL) {
- X binf = NULL;
- X return(bin);
- X } else {
- X binf = str3save(bin, SFNDELIM, base);
- X return (binf);
- X }
- X}
- X
- X/*
- X - cd - change to a directory, with checking
- X */
- Xvoid
- Xcd(dir)
- Xchar *dir;
- X{
- X if (pwd != NULL)
- X free(pwd);
- X if (chdir(dir) < 0)
- X errunlock("cannot chdir(%s)", dir);
- X pwd = strsave(dir);
- X}
- X
- X/*
- X - newspath - search path for normal system commands
- X */
- Xchar *
- Xnewspath()
- X{
- X DIRS();
- X return(path);
- X}
- X
- X/*
- X - newsumask - suitable value of umask for news stuff
- X */
- Xint
- Xnewsumask()
- X{
- X DIRS();
- X return(numask);
- X}
- X
- X/*
- X - newsmaster - mail address to complain to
- X */
- Xchar *
- Xnewsmaster()
- X{
- X DIRS();
- X return(nmaster);
- X}
- !
- echo 'libcnews/gethdr.c':
- sed 's/^X//' >'libcnews/gethdr.c' <<'!'
- X/*
- X * gethdr - read an entire RFC 822 header "line", including continuations
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <fgetmfs.h>
- X#include <sys/types.h>
- X#include "news.h"
- X#include "libc.h"
- X
- X/*
- X * Read the first line; if it's a header, repeatedly read lines until a
- X * non-continuation line is found. For each continuation line, grow
- X * hdr to accomodate it and append it to hdr.
- X * *limitp is updated by subtracting the number of bytes read.
- X *
- X */
- Xchar * /* malloced; caller must not free */
- Xgethdr(in, limitp, ishdrp)
- XFILE *in;
- Xregister long *limitp;
- Xint *ishdrp;
- X{
- X register int c, hdrlen, contlen, limitset = *limitp >= 0;
- X register char *contin = NULL;
- X static char *hdr = NULL;
- X
- X nnfree(&hdr);
- X *ishdrp = NO;
- X hdr = fgetmfs(in, (int)*limitp, CONT_NO);
- X if (hdr == NULL)
- X return hdr;
- X hdrlen = strlen(hdr);
- X *limitp -= hdrlen;
- X *ishdrp = ishdr(hdr);
- X if (!*ishdrp)
- X return hdr;
- X while (hdr != NULL && (!limitset || *limitp > 1) && (c = getc(in)) != EOF) {
- X (void) ungetc(c, in);
- X
- X if (!iswhite(c))
- X break;
- X contin = fgetmfs(in, (int)*limitp, CONT_NO);
- X if (contin == NULL)
- X break;
- X
- X contlen = strlen(contin);
- X *limitp -= contlen;
- X hdr = realloc(hdr, (unsigned)(hdrlen + contlen + 1)); /* 1 for NUL */
- X if (hdr != NULL) {
- X (void) strcpy(hdr + hdrlen, contin);
- X hdrlen += contlen;
- X }
- X free(contin);
- X contin = NULL;
- X }
- X return hdr;
- X}
- X
- X
- X/*
- X * Is s an RFC 822 header line?
- X * If a colon is seen before whitespace, it is.
- X */
- Xint
- Xishdr(s)
- Xregister char *s;
- X{
- X register char *cp = s;
- X register int c;
- X
- X while ((c = *cp) != '\0' && !(isascii(c) && isspace(c)) && c != ':')
- X ++cp;
- X return c == ':' && cp > s;
- X}
- !
- echo 'libcnews/strlower.c':
- sed 's/^X//' >'libcnews/strlower.c' <<'!'
- X/*
- X * make a string all lower-case.
- X */
- X
- X#include <ctype.h>
- X
- Xstrlower(s)
- Xregister char *s;
- X{
- X for (; *s != '\0'; ++s)
- X if (isascii(*s) && isupper(*s))
- X *s = tolower(*s);
- X}
- !
- echo 'libcnews/complain.c':
- sed 's/^X//' >'libcnews/complain.c' <<'!'
- X#include <stdio.h>
- X
- X/*
- X - complain - lodge a complaint
- X */
- Xvoid
- Xcomplain(s1, s2)
- Xchar *s1;
- Xchar *s2;
- X{
- X extern char *progname;
- X
- X (void) fprintf(stderr, "%s: ", progname);
- X (void) fprintf(stderr, s1, s2);
- X (void) putc('\n', stderr);
- X}
- !
- echo 'libcnews/ngmatch.c':
- sed 's/^X//' >'libcnews/ngmatch.c' <<'!'
- X/*
- X * ngmatch - newsgroup name matching
- X *
- X * ngmatch returns true iff the newsgroup(s) in ngs match
- X * the pattern(s) in ngpat, where
- X *
- X * ngpats: { ngpat { "," ngpat }* }?
- X * ngpat: "!"? word { "." word }*
- X * word: { alphanum }+ | "all"
- X *
- X * Only one group need match for success. (Redundant?)
- X *
- X * For each group, note the depth of each match against the patterns,
- X * negated or not. Ignore mismatches. The deepest match wins at the end;
- X * if it's a tie, negated matches are rejections.
- X *
- X * A match of any group against the patterns is a success.
- X * Failure to match any pattern with a group is a mismatch of that group.
- X * Failure to match any group against any pattern is a total failure.
- X *
- X * "all" in a pattern is a wildcard that matches exactly one word;
- X * it does not cross "." (NGDELIM) delimiters.
- X */
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <sys/types.h>
- X#include "news.h"
- X
- X#define truth(bool) ((bool)? "yes": "no")
- X
- X#ifndef STATIC
- X#define STATIC /* static */
- X#endif
- X
- X#define ALL "all" /* word wildcard */
- X
- X/* private */
- Xstatic boolean debug = NO;
- X
- X/* forwards */
- Xextern boolean mpatsmatch();
- X
- Xvoid
- Xmatchdebug(state)
- Xboolean state;
- X{
- X debug = state;
- X}
- X
- Xboolean
- Xngmatch(ngpat, ngs)
- Xchar *ngpat, *ngs;
- X{
- X register char *ngp; /* point at current group */
- X register char *ngcomma;
- X register char *rngpat = ngpat;
- X
- X if (debug)
- X (void) fprintf(stderr, "ngmatch(`%s', `%s')\n", rngpat, ngs);
- X for (ngp = ngs; ngp != NULL; ngp = ngcomma) {
- X register boolean match;
- X
- X INDEX(ngp, NGSEP, ngcomma);
- X if (ngcomma != NULL)
- X *ngcomma = '\0'; /* will be restored below */
- X match = mpatsmatch(rngpat, ngp); /* try 1 group, n-patterns */
- X if (ngcomma != NULL)
- X *ngcomma++ = NGSEP; /* point after the comma */
- X if (match)
- X return YES;
- X }
- X return NO; /* no pattern matched any group */
- X}
- X
- X/*
- X * Match one group against multiple patterns, as above.
- X * The key is to keep track of how deeply plain and negated patterns matched.
- X */
- XSTATIC boolean
- Xmpatsmatch(ngpat, grp)
- Xchar *ngpat, *grp;
- X{
- X register char *patp; /* point at current pattern */
- X register char *patcomma;
- X register int depth;
- X register int faildeepest = 0, hitdeepest = 0; /* in case no match */
- X register boolean negation;
- X
- X if (debug)
- X (void) fprintf(stderr, "mpatsmatch(`%s', `%s')\n", ngpat, grp);
- X for (patp = ngpat; patp != NULL; patp = patcomma) {
- X negation = NO;
- X INDEX(patp, NGSEP, patcomma);
- X if (patcomma != NULL)
- X *patcomma = '\0'; /* will be restored below */
- X if (*patp == NGNEG) {
- X ++patp;
- X negation = YES;
- X }
- X depth = onepatmatch(patp, grp); /* try 1 pattern, 1 group */
- X if (patcomma != NULL)
- X *patcomma++ = NGSEP; /* point after the comma */
- X if (depth == 0) /* mis-match */
- X ; /* ignore it */
- X else if (negation) {
- X /* record ordinal # of deepest negated matched word */
- X if (depth > faildeepest)
- X faildeepest = depth;
- X } else {
- X /* record ordinal # of deepest plain matched word */
- X if (depth > hitdeepest)
- X hitdeepest = depth;
- X }
- X }
- X if (debug)
- X (void) fprintf(stderr, "mpatsmatch(`%s', `%s') returns %s\n",
- X ngpat, grp, truth(hitdeepest > faildeepest));
- X return hitdeepest > faildeepest;
- X}
- X
- X/*
- X * Match a pattern against a group by looking at each word of pattern in turn.
- X *
- X * On a match, return the ordinal number of the rightmost word that matches.
- X * If group runs out first, the match fails; else it succeeds.
- X * On a failure, return zero.
- X */
- XSTATIC int
- Xonepatmatch(patp, grp)
- Xchar *patp, *grp;
- X{
- X register char *rpatwd; /* used by word match (inner loop) */
- X register char *patdot, *grdot; /* point at dots after words */
- X register char *patwd, *grwd; /* point at current words */
- X register int depth = 0;
- X
- X for (patwd = patp, grwd = grp; patwd != NULL && grwd != NULL;
- X patwd = patdot, grwd = grdot, depth++) {
- X register boolean match;
- X
- X /* null-terminate words */
- X INDEX(patwd, NGDELIM, patdot);
- X if (patdot != NULL)
- X *patdot = '\0'; /* will be restored below */
- X INDEX(grwd, NGDELIM, grdot);
- X if (grdot != NULL)
- X *grdot = '\0'; /* will be restored below */
- X
- X /*
- X * Match one word of pattern with one word of group.
- X * A pattern word of "all" matches any group word.
- X */
- X#ifdef FAST_STRCMP
- X match = STREQ(patwd, grwd) || STREQ(patwd, ALL);
- X#else
- X match = NO;
- X for (rpatwd = patwd; *rpatwd == *grwd++; )
- X if (*rpatwd++ == '\0') {
- X match = YES; /* literal match */
- X break;
- X }
- X if (!match) {
- X /* ugly special case match for "all" */
- X rpatwd = patwd;
- X match = *rpatwd++ == 'a' && *rpatwd++ == 'l' &&
- X *rpatwd++ == 'l' && *rpatwd == '\0';
- X }
- X#endif /* FAST_STRCMP */
- X
- X if (patdot != NULL)
- X *patdot++ = NGDELIM; /* point after the dot */
- X if (grdot != NULL)
- X *grdot++ = NGDELIM;
- X if (!match) {
- X depth = 0; /* words differed - mismatch */
- X break;
- X }
- X }
- X /* if group name ran out before pattern, then match fails */
- X if (grwd == NULL && patwd != NULL)
- X depth = 0;
- X if (debug)
- X (void) fprintf(stderr, "onepatmatch(`%s', `%s') returns %d\n",
- X patp, grp, depth);
- X return depth;
- X}
- X
- X#ifdef CROSS_POSTINGS_RESTRICTED
- X/*
- X * ngtopsame(ngs) - true iff ngs are all in the same top-level distribution
- X */
- Xboolean
- Xngtopsame(ngs)
- Xregister char *ngs;
- X{
- X register char *nextng;
- X
- X INDEX(ngs, NGSEP, nextng);
- X if (nextng == NULL) /* no groups left */
- X return YES;
- X ++nextng; /* skip NGSEP */
- X return firstsame(ngs, nextng) && ngtopsame(nextng);
- X}
- X
- X/*
- X * firstsame(ng1, ng2) - true iff first characters (up to the first
- X * NGDELIM or NGSEP) are the same in each string. Neither string
- X * is guaranteed to be null-terminated (a small lie; one *is*).
- X */
- XSTATIC boolean
- Xfirstsame(ng1, ng2)
- Xregister char *ng1, *ng2;
- X{
- X register int ng1brk;
- X static char delimstr[] = { NGSEP, NGDELIM, '\0' };
- X extern int strcspn();
- X
- X ng1brk = strcspn(ng1, delimstr);
- X return ng1brk == strcspn(ng2, delimstr) && STREQN(ng1, ng2, ng1brk);
- X}
- X#endif /* CROSS_POSTINGS_RESTRICTED */
- !
- echo 'libcnews/time.c':
- sed 's/^X//' >'libcnews/time.c' <<'!'
- X/*
- X * time utilities
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/timeb.h>
- X#include "libc.h"
- X#include "news.h"
- X
- X/*
- X * Write a timestamp of the form "Jun 12 12:34:56.789" on fp.
- X * N.B.: no trailing newline is written.
- X */
- Xvoid
- Xtimestamp(fp, timep)
- XFILE *fp;
- Xtime_t *timep; /* if non-null, return time() here for later use */
- X{
- X struct timeb ftnow;
- X char ms[4]; /* room for "123" and a NUL */
- X
- X ftime(&ftnow);
- X if (timep != NULL)
- X *timep = ftnow.time;
- X /* .15 excludes yyyy\n\0; + 4 omits day-of-week */
- X (void) fprintf(fp, "%.15s.", ctime(&ftnow.time) + 4);
- X (void) ltoza(ms, (long)ftnow.millitm, 3); /* 3 digits of output */
- X (void) fputs(ms, fp);
- X}
- !
- echo 'libcnews/nemalloc.c':
- sed 's/^X//' >'libcnews/nemalloc.c' <<'!'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "libc.h"
- X
- Xchar *
- Xnemalloc(size) /* news emalloc - calls errunlock on error */
- Xunsigned size;
- X{
- X register char *result = malloc(size);
- X
- X if (result == NULL)
- X errunlock("out of memory", "");
- X return result;
- X}
- !
- echo 'libcnews/ltoza.c':
- sed 's/^X//' >'libcnews/ltoza.c' <<'!'
- X/*
- X * ltoza, ltozan - long to zero-padded ascii conversions
- X *
- X * These functions exist only because there is no portable way
- X * to do this with printf and there may be no way do it at all
- X * with printf on V7, due to a bug in V7's printf.
- X */
- X#include <stdlib.h>
- X
- X#define RADIX 10
- X
- X/*
- X * convert value to at most width characters in outstr, padding with
- X * zeros on the left (after any sign); do not terminate with a NUL.
- X * returns true iff the value fits in width characters.
- X */
- Xint /* boolean */
- Xltozan(outstr, value, width)
- Xchar *outstr;
- Xlong value;
- Xint width;
- X{
- X register char *op = outstr;
- X register long wval = value;
- X register int wwid = width;
- X
- X if (wval < 0 && wwid > 0) {
- X *op++ = '-';
- X --wwid;
- X wval = -wval; /* fails on smallest int; tough */
- X }
- X op += wwid - 1; /* find right end */
- X while (wwid-- > 0) { /* generate "wwid" digits */
- X register ldiv_t result;
- X
- X result = ldiv(wval, (long)RADIX); /* shades of V6! */
- X wval = result.quot;
- X *op-- = result.rem + '0';
- X }
- X return wval == 0;
- X}
- X
- X/*
- X * convert value to at most width characters in outstr, padding with
- X * zeros on the left (after any sign); terminate with a NUL.
- X */
- Xint /* boolean */
- Xltoza(outstr, value, width)
- Xregister char *outstr; /* char outstr[width+1]; */
- Xlong value;
- Xregister int width;
- X{
- X register int fits = ltozan(outstr, value, width);
- X
- X outstr[width] = '\0';
- X return fits;
- X}
- !
- echo 'libcnews/str3save.c':
- sed 's/^X//' >'libcnews/str3save.c' <<'!'
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "libc.h"
- X#include "news.h"
- X
- X/*
- X - str3save - malloc space for 3 strings, concatenated, and concatenate them
- X * This may seem kind of ad-hoc, but it's just right for filename work.
- X */
- Xchar *
- Xstr3save(s1, s2, s3)
- Xchar *s1;
- Xchar *s2;
- Xchar *s3;
- X{
- X register char *p;
- X static char *empty = "";
- X
- X if (s1 == NULL)
- X s1 = empty;
- X if (s2 == NULL)
- X s2 = empty;
- X if (s3 == NULL)
- X s3 = empty;
- X
- X p = nemalloc((unsigned)(strlen(s1) + strlen(s2) + strlen(s3) + 1));
- X (void) strcpy(p, s1);
- X (void) strcat(p, s2);
- X (void) strcat(p, s3);
- X return(p);
- X}
- !
- echo 'libcnews/lock.c':
- sed 's/^X//' >'libcnews/lock.c' <<'!'
- X/*
- X * C news system locking.
- X * It's compatible with B 2.10.1 news, except that locks are never
- X * declared stale (blow 'em away in /etc/rc).
- X * Only permit relaynews to run on a file server to make this sane.
- X */
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <sys/types.h>
- X#include "libc.h"
- X#include "news.h"
- X#include "config.h"
- X
- X#define LOCKNAME "LOCK"
- X#define LOCKTEMP "LOCKTMXXXXXX"
- X#define INTERVAL 25 /* seconds to sleep on a busy lock */
- X
- Xstatic boolean debug = NO;
- Xstatic boolean mylock = NO;
- X
- Xvoid
- Xlockdebug(state)
- Xboolean state;
- X{
- X debug = state;
- X}
- X
- X/*
- X * lock the news system.
- X * create a temporary name in $NEWSCTL for linking, store my pid in it.
- X * repeatedly try to link the temporary name to LOCKNAME.
- X */
- Xvoid
- Xnewslock()
- X{
- X register char *tempnm, *lockfile;
- X register FILE *tempfp;
- X int locktries = 0;
- X
- X tempnm = strsave(ctlfile(LOCKTEMP));
- X (void) mktemp(tempnm);
- X tempfp = fopen(tempnm, "w");
- X if (tempfp == NULL)
- X error("can't create lock temporary `%s'", tempnm);
- X (void) fprintf(tempfp, "%d\n", getpid());
- X (void) fclose(tempfp);
- X
- X lockfile = strsave(ctlfile(LOCKNAME));
- X while (link(tempnm, lockfile) < 0) {
- X if (errno != EEXIST)
- X error("can't link `%s' to LOCK", tempnm);
- X /*
- X * Could decide here if the lock is stale.
- X * If so, remove it and try again to lock.
- X */
- X if (debug && ++locktries == 1)
- X (void) printf("%s: sleeping on LOCK\n", progname);
- X sleep(INTERVAL);
- X }
- X free(lockfile);
- X (void) unlink(tempnm);
- X free(tempnm);
- X mylock = YES;
- X}
- X
- Xvoid
- Xnewsunlock()
- X{
- X if (mylock) {
- X (void) unlink(ctlfile(LOCKNAME));
- X mylock = NO;
- X }
- X}
- X
- Xvoid
- Xerrunlock(fmt, s) /* like error(3), but unlock before exit */
- Xchar *fmt, *s;
- X{
- X warning(fmt, s);
- X newsunlock();
- X exit(1);
- X /* NOTREACHED */
- X}
- !
- echo 'libcnews/fopenclex.c':
- sed 's/^X//' >'libcnews/fopenclex.c' <<'!'
- X/*
- X * fopen and set close-on-exec (to avoid leaking descriptors into children)
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "news.h"
- X
- XFILE *
- Xfopenwclex(name, mode) /* open name; close-on-exec if OK, else warning */
- Xchar *name, *mode;
- X{
- X register FILE *fp;
- X
- X if ((fp = fopenclex(name, mode)) == NULL)
- X warning("can't open `%s'", name);
- X return fp;
- X}
- X
- XFILE *
- Xfopenclex(file, mode) /* open file and if OK, close-on-exec */
- Xchar *file, *mode;
- X{
- X register FILE *fp;
- X
- X if ((fp = fopen(file, mode)) != NULL)
- X fclsexec(fp);
- X return fp;
- X}
- !
- echo 'libcnews/string.c':
- sed 's/^X//' >'libcnews/string.c' <<'!'
- X/*
- X * string operations
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <sys/types.h>
- X#include "libc.h"
- X#include "news.h"
- X
- X/* forwards */
- Xchar *findhost();
- X
- X/*
- X * Return strsave() of the first word in "tokens".
- X * Words are delimited by spaces.
- X */
- Xchar *
- Xfirst(tokens)
- Xchar *tokens;
- X{
- X return strsvto(tokens, ' ');
- X}
- X
- X/*
- X * Turn a newsgroup name into a file name, in place.
- X */
- Xvoid
- Xmkfilenm(ng)
- Xregister char *ng;
- X{
- X for (; *ng != '\0'; ng++)
- X if (*ng == NGDELIM)
- X *ng = FNDELIM;
- X}
- X
- Xvoid
- Xtrim(s) /* trim trailing newline */
- Xchar *s;
- X{
- X register char *nl;
- X
- X INDEX(s, '\n', nl);
- X if (nl != NULL)
- X *nl = '\0';
- X}
- X
- Xchar *
- Xskipsp(s) /* skip any whitespace at *s */
- Xregister char *s;
- X{
- X while (iswhite(*s))
- X s++;
- X return s;
- X}
- X
- Xchar *
- Xstrsvto(s, c) /* save s up to (but excluding) c */
- Xchar *s;
- Xint c;
- X{
- X register char *endp, *copy;
- X
- X endp = index(s, c); /* find interesting part's end of s */
- X if (endp != NULL)
- X *endp = '\0'; /* restored below */
- X copy = strsave(s); /* copy interesting substring of s */
- X if (endp != NULL)
- X *endp = c;
- X return copy;
- X}
- X
- Xint
- Xcharcount(s, c) /* how many c's in s? */
- Xregister char *s;
- Xregister int c;
- X{
- X register int count = 0;
- X
- X#ifdef CLASSY
- X for (; (s = index(s, c)) != NULL; s = (s == NULL? NULL: s+1))
- X ++count;
- X#else
- X while (*s != '\0')
- X if (*s++ == c)
- X ++count;
- X#endif /* CLASSY */
- X return count;
- X}
- X
- Xchar *
- Xnullify(s) /* return s or "" if NULL */
- Xregister char *s;
- X{
- X if (s == NULL)
- X return "";
- X else
- X return s;
- X}
- X
- X/*
- X * If c is NUL, hostchar will be false, so don't test (optimisation: ==).
- X */
- X#define nothostchar(c, ch) (!hostchar(c, ch) /* || (c) == '\0' */ )
- X/*
- X * True if c can be part of a hostname. RFC 850 allows letters, digits, periods,
- X * and hyphens and specifically disallows blanks. False may mean c is NUL.
- X */
- X#define hostchar(c, ch) ((ch) = (c), \
- X (isascii(ch) && isalnum(ch) || (ch) == '.' || (ch) == '-'))
- X
- X/*
- X * Return true iff any host in hosts appears in s, as per hostin().
- X * hosts are separated by non-hostname characters.
- X */
- Xboolean
- Xanyhostin(hosts, s)
- Xchar *hosts, *s;
- X{
- X register char *host = hosts;
- X
- X while (*host != '\0') {
- X register char *delimp;
- X register int ch;
- X register int delim;
- X register boolean hostisin;
- X
- X while (nothostchar(*host, ch) && *host != '\0')
- X ++host; /* skip leading delims */
- X if (*host == '\0') /* no more hosts */
- X break;
- X for (delimp = host; hostchar(*delimp, ch); delimp++)
- X ; /* skip to next delim */
- X delim = *delimp; /* may be NUL */
- X *delimp = '\0'; /* terminate host */
- X hostisin = hostin(host, s);
- X *delimp = delim; /* restore hosts delimiter */
- X if (hostisin)
- X return YES;
- X host = delimp; /* advance to next host */
- X }
- X return NO;
- X}
- X
- X/*
- X * Return true iff host appears in s, with no characters from the alphabet
- X * of legal hostname characters immediately adjacent.
- X */
- Xboolean
- Xhostin(host, s)
- Xregister char *host, *s;
- X{
- X return findhost(host, s) != NULL;
- X}
- X
- X/*
- X * Return the number of machines appearing in path,
- X * by counting transitions from delimiters.
- X * See hostin() for the rules, and the macros.
- X */
- Xint
- Xhopcount(path)
- Xregister char *path;
- X{
- X register int count = 0;
- X register int ch;
- X
- X for (; *path != '\0'; path++)
- X if (nothostchar(path[0], ch) &&
- X (hostchar(path[1], ch) || path[1] == '\0'))
- X ++count; /* trailing edge of delimiters */
- X return count;
- X}
- X
- Xchar *
- Xsendersite(path)
- Xregister char *path;
- X{
- X register char *p;
- X register int ch;
- X static char *sender = NULL;
- X
- X nnfree(&sender); /* free the last answer */
- X for (p = path; hostchar(*p, ch); p++)
- X ;
- X if (*p == '\0') /* only a user name */
- X return hostname(); /* a local posting */
- X else {
- X register int delim = *p;
- X
- X *p = '\0';
- X sender = strsave(path); /* copy the first machine name */
- X *p = delim;
- X return sender;
- X }
- X}
- X
- X/*
- X * Canonicalise rawpath: NULL -> "", chop last site (actually user name) but not
- X * its leading delimiter, and if Approved:, chop everything after the site,
- X * and its trailing delimiter, from Approved: (or Sender:) (user@host).
- X * Result is malloced memory.
- X */
- Xchar *
- Xcanonpath(rawpath, approved, sender)
- Xchar *rawpath, *approved, *sender;
- X{
- X register char *newpath = strsave(nullify(rawpath));
- X register char *p, *lastdelim = newpath, *site = NULL;
- X register int ch;
- X
- X for (p = newpath; *p != '\0'; ++p)
- X if (nothostchar(*p, ch))
- X lastdelim = p + 1; /* just past delim */
- X if (lastdelim != NULL)
- X *lastdelim = '\0'; /* omit user's name */
- X
- X if (approved != NULL) { /* moderated article */
- X site = index(approved, '@');
- X if (site == NULL)
- X site = index(nullify(sender), '@');
- X }
- X if (site != NULL) {
- X p = findhost(site+1, newpath);
- X if (p != NULL && *p++ != '\0') /* delim after site? */
- X *p = '\0'; /* terminate newpath after site */
- X }
- X return newpath;
- X}
- X
- X/*
- X * Return pointer to the first byte after host in path, if any,
- X * with no characters from the alphabet of legal hostname characters
- X * immediately adjacent.
- X * This function is a profiling hot spot, so it has been optimised.
- X */
- Xchar *
- Xfindhost(host, path)
- Xregister char *host, *path;
- X{
- X register int hostlen = strlen(host), ch;
- X
- X /* Special case: match host!path or host. */
- X if (STREQN(path, host, hostlen) && nothostchar(path[hostlen], ch))
- X return &path[hostlen];
- X
- X /* Match path2!host!path or path2!host. */
- X while (*path != '\0')
- X if (hostchar(path[0], ch)) /* can't start after here */
- X ++path;
- X else if ((++path, STREQN(path, host, hostlen)) &&
- X nothostchar(path[hostlen], ch))
- X return &path[hostlen];
- X return NULL;
- X}
- !
- echo 'libcnews/hostname.c':
- sed 's/^X//' >'libcnews/hostname.c' <<'!'
- X/*
- X * hostname - return the Usenet name of this machine
- X *
- X * One interesting possibility would be to assume that the first
- X * name in the sys file is our Usenet name, unless it is "ME",
- X * which would require our current strategy anyway.
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X
- X#include "libc.h"
- X#include "news.h"
- X#include "config.h"
- X
- X/* 2BSD funniness */
- X#ifdef BSD2_10
- X# include <short_names.h>
- X#endif
- X
- X#ifndef NAMEFILE
- X#define NAMEFILE ctlfile("whoami")
- X#endif
- X
- Xchar *
- Xhostname() /* return this Usenet machine's name */
- X{
- X static char name[MAXHOST];
- X
- X if (name[0] == '\0') { /* try to get the "news hostname" */
- X register FILE *fp;
- X
- X fp = fopenclex(NAMEFILE, "r");
- X if (fp != NULL) {
- X (void) fgets(name, sizeof name, fp);
- X (void) nfclose(fp);
- X if (name[0] != '\0' && name[strlen(name) - 1] == '\n')
- X name[strlen(name) - 1] = '\0';
- X }
- X }
- X if (name[0] == '\0') /* else use the ordinary hostname */
- X (void) gethostname(name, sizeof name);
- X return name;
- X}
- !
- echo 'libcnews/strsave.c':
- sed 's/^X//' >'libcnews/strsave.c' <<'!'
- X/*
- X * strsave - like strdup, but error if can't allocate
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "libc.h"
- X#include "news.h"
- X
- X/*
- X * Copy "s" into malloced memory, if any is available.
- X * If not, unlock the news system, print a message and exit,
- X * else return the address of the malloced memory.
- X */
- Xchar *
- Xstrsave(s)
- Xregister char *s;
- X{
- X register char *news =nemalloc((unsigned)strlen(s)+1); /* include NUL */
- X
- X (void) strcpy(news, s);
- X return news;
- X}
- !
- echo 'libcnews/Makefile':
- sed 's/^X//' >'libcnews/Makefile' <<'!'
- X# libcnews makefile
- XINCLUDE=../include
- XDEFINES=-I$(INCLUDE)
- XCOPTS= -O # -pg -p
- XCFLAGS= $(COPTS) $(DEFINES)
- XLINTFLAGS=-hau $(DEFINES)
- XLIB=libcnews.a
- X# RANLIB is ranlib on non-USG systems, echo on USG systems
- XRANLIB=ranlib
- X#RANLIB=:
- XSRCS=complain.c config.c fopenclex.c hostname.c \
- X lock.c ltoza.c ngmatch.c readline.c \
- X string.c strlower.c strsave.c str3save.c time.c
- XOBJS = complain.o config.o fopenclex.o gethdr.o hostname.o lock.o ltoza.o \
- X nemalloc.o ngmatch.o str3save.o string.o strlower.o strsave.o time.o
- X# workaround for System V make bug
- XSHELL = /bin/sh
- X
- Xu: $(OBJS)
- X ar ruv ../libcnews.a $(OBJS)
- X
- Xall: $(OBJS)
- X
- X$(LIB): $(SRCS)
- X $(CC) $(CFLAGS) -c $?
- X ar rv $@ *.o
- X rm *.o
- X $(RANLIB) $@
- X
- Xlint:
- X lint $(LINTFLAGS) $(SRCS)
- X
- Xclean:
- X rm -f *.o
- X
- X# header dependencies for libcnews.a
- Xconfig.o: $(INCLUDE)/news.h $(INCLUDE)/config.h
- Xlock.o: $(INCLUDE)/news.h
- Xngmatch.o: $(INCLUDE)/news.h
- Xtime.o: $(INCLUDE)/news.h
- X# ltoza.o: $(INCLUDE)/stdlib.h # trouble if stdlib.h is system one, not ours
- !
- echo 'libfake/getopt.3':
- sed 's/^X//' >'libfake/getopt.3' <<'!'
- X.TH GETOPT 3 local
- X.DA 25 March 1982
- X.SH NAME
- Xgetopt \- get option letter from argv
- X.SH SYNOPSIS
- X.ft B
- Xint getopt(argc, argv, optstring)
- X.br
- Xint argc;
- X.br
- Xchar **argv;
- X.br
- Xchar *optstring;
- X.sp
- Xextern char *optarg;
- X.br
- Xextern int optind;
- X.ft
- X.SH DESCRIPTION
- X.I Getopt
- Xreturns the next option letter in
- X.I argv
- Xthat matches a letter in
- X.IR optstring .
- X.I Optstring
- Xis a string of recognized option letters;
- Xif a letter is followed by a colon, the option is expected to have
- Xan argument that may or may not be separated from it by white space.
- X.I Optarg
- Xis set to point to the start of the option argument on return from
- X.IR getopt .
- X.PP
- X.I Getopt
- Xplaces in
- X.I optind
- Xthe
- X.I argv
- Xindex of the next argument to be processed.
- XBecause
- X.I optind
- Xis external, it is normally initialized to zero automatically
- Xbefore the first call to
- X.IR getopt .
- X.PP
- XWhen all options have been processed (i.e., up to the first
- Xnon-option argument),
- X.I getopt
- Xreturns
- X.BR EOF .
- XThe special option
- X.B \-\-
- Xmay be used to delimit the end of the options;
- X.B EOF
- Xwill be returned, and
- X.B \-\-
- Xwill be skipped.
- X.SH SEE ALSO
- Xgetopt(1)
- X.SH DIAGNOSTICS
- X.I Getopt
- Xprints an error message on
- X.I stderr
- Xand returns a question mark
- X.RB ( ? )
- Xwhen it encounters an option letter not included in
- X.IR optstring .
- X.SH EXAMPLE
- XThe following code fragment shows how one might process the arguments
- Xfor a command that can take the mutually exclusive options
- X.B a
- Xand
- X.BR b ,
- Xand the options
- X.B f
- Xand
- X.BR o ,
- Xboth of which require arguments:
- X.PP
- X.RS
- X.nf
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int c;
- X extern int optind;
- X extern char *optarg;
- X \&.
- X \&.
- X \&.
- X while ((c = getopt(argc, argv, "abf:o:")) != EOF)
- X switch (c) {
- X case 'a':
- X if (bflg)
- X errflg++;
- X else
- X aflg++;
- X break;
- X case 'b':
- X if (aflg)
- X errflg++;
- X else
- X bproc();
- X break;
- X case 'f':
- X ifile = optarg;
- X break;
- X case 'o':
- X ofile = optarg;
- X break;
- X case '?':
- X default:
- X errflg++;
- X break;
- X }
- X if (errflg) {
- X fprintf(stderr, "Usage: ...");
- X exit(2);
- X }
- X for (; optind < argc; optind++) {
- X \&.
- X \&.
- X \&.
- X }
- X \&.
- X \&.
- X \&.
- X}
- X.RE
- X.PP
- XA template similar to this can be found in
- X.IR /usr/pub/template.c .
- X.SH HISTORY
- XWritten by Henry Spencer, working from a Bell Labs manual page.
- XBehavior believed identical to the Bell version.
- X.SH BUGS
- XIt is not obvious how
- X`\-'
- Xstanding alone should be treated; this version treats it as
- Xa non-option argument, which is not always right.
- X.PP
- XOption arguments are allowed to begin with `\-';
- Xthis is reasonable but reduces the amount of error checking possible.
- X.PP
- X.I Getopt
- Xis quite flexible but the obvious price must be paid: there is much
- Xit could do that it doesn't, like
- Xchecking mutually exclusive options, checking type of
- Xoption arguments, etc.
- !
- echo 'libfake/getopt.c':
- sed 's/^X//' >'libfake/getopt.c' <<'!'
- X/*
- X * getopt - get option letter from argv
- X */
- X
- X#include <stdio.h>
- X
- Xchar *optarg; /* Global argument pointer. */
- Xint optind = 0; /* Global argv index. */
- X
- Xstatic char *scan = NULL; /* Private scan pointer. */
- X
- Xextern char *index();
- X
- Xint
- Xgetopt(argc, argv, optstring)
- Xint argc;
- Xchar *argv[];
- Xchar *optstring;
- X{
- X register char c;
- X register char *place;
- X
- X optarg = NULL;
- X
- X if (scan == NULL || *scan == '\0') {
- X if (optind == 0)
- X optind++;
- X
- X if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
- X return(EOF);
- X if (strcmp(argv[optind], "--")==0) {
- X optind++;
- X return(EOF);
- X }
- X
- X scan = argv[optind]+1;
- X optind++;
- X }
- X
- X c = *scan++;
- X place = index(optstring, c);
- X
- X if (place == NULL || c == ':') {
- X fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
- X return('?');
- X }
- X
- X place++;
- X if (*place == ':') {
- X if (*scan != '\0') {
- X optarg = scan;
- X scan = NULL;
- X } else if (optind < argc) {
- X optarg = argv[optind];
- X optind++;
- X } else {
- X fprintf(stderr, "%s: -%c argument missing\n", argv[0], c);
- X return('?');
- X }
- X }
- X
- X return(c);
- X}
- !
- echo 'libfake/ldiv.c':
- sed 's/^X//' >'libfake/ldiv.c' <<'!'
- X/*
- X * ANSI's ldiv(num, denom) - yields (num/denom, num%denom)
- X */
- X
- X#include <stdlib.h>
- X
- Xldiv_t
- Xldiv(num, denom)
- Xregister long num, denom;
- X{
- X register ldiv_t result;
- X
- X result.quot = num/denom;
- X result.rem = num%denom;
- X return result;
- X}
- !
- echo 'libfake/README':
- sed 's/^X//' >'libfake/README' <<'!'
- XThis is stuff that your system ought to have but might not. Some of these
- Xare just quick fakes that do the right thing for C News but not in general;
- Xsome are freely-redistributable portable implementations of the real thing.
- X
- XThe dbm imitation is exceedingly crude and inefficient but provides full
- Xfunctionality.
- X
- XFsync and symlink are C-News-specific fakes.
- X
- XLdiv.c is inefficient but provides the full ANSI C functionality. (Do not
- Xconfuse it with the prehistoric ldiv function found in some very old Unixes.)
- X
- XThe mem* and str* and *index functions come from Henry Spencer's public-domain
- Xstring-functions implementation. Said implementation is somewhat in need of
- Xan updating to match ANSI C, and there are minor portability glitches, but in
- Xgeneral these should do the right thing for you.
- X
- XGetopt is Henry Spencer's public-domain implementation of System III getopt.
- XIt differs from the System V one in minor ways.
- X
- XMkdir may give problems if called from a setuid program and either your
- Xsystem does not implement setuid(geteuid()) or the program doesn't bother
- Xto do it. Otherwise it's fine.
- X
- XPutenv is crude but works.
- !
- echo 'libfake/putenv.c':
- sed 's/^X//' >'libfake/putenv.c' <<'!'
- X/*
- X * putenv - add a variable to the environment, as in SysV
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include "libc.h"
- X
- X#define YES 1
- X#define NO 0
- X
- X/* peculiar return values */
- X#define WORKED 0
- X#define FAILED 1
- X
- Xint
- Xputenv(var) /* put var in the environment */
- Xchar *var;
- X{
- X register char **envp, **newenv;
- X register int oldenvcnt;
- X extern char **environ;
- X
- X /* count variables, look for var */
- X for (envp = environ; *envp != 0; envp++) {
- X register char *varp = var, *ep = *envp;
- X register int namesame;
- X
- X namesame = NO;
- X for (; *varp == *ep && *varp != '\0'; ++ep, ++varp)
- X if (*varp == '=')
- X namesame = YES;
- X if (*varp == *ep && *ep == '\0')
- X return WORKED; /* old & new var's are the same */
- X if (namesame) {
- X *envp = var; /* replace var with new value */
- X return WORKED;
- X }
- X }
- X oldenvcnt = envp - environ;
- X
- X /* allocate new environment with room for one more variable */
- X newenv = (char **)malloc((unsigned)((oldenvcnt+1+1)*sizeof(*envp)));
- X if (newenv == NULL)
- X return FAILED;
- X
- X /* copy old environment pointers, add var, switch environments */
- X (void) memcpy((char *)newenv, (char *)environ, oldenvcnt*sizeof(*envp));
- X newenv[oldenvcnt] = var;
- X newenv[oldenvcnt+1] = NULL;
- X environ = newenv;
- X return WORKED;
- X}
- !
- echo 'libfake/Makefile':
- sed 's/^X//' >'libfake/Makefile' <<'!'
- XINCLUDE = ../include
- XCOPTS = -O
- XCFLAGS = $(COPTS) -I$(INCLUDE)
- X# workaround for System V make bug
- XSHELL = /bin/sh
- X
- XALL = dbm.o fsync.o getopt.o index.o ldiv.o memchr.o memcmp.o memcpy.o \
- Xmemset.o mkdir.o putenv.o rindex.o strchr.o strcspn.o strpbrk.o strrchr.o \
- Xstrspn.o strtok.o symlink.o
- X
- X# beware -- build knows about NEEDED
- XNEEDED = ldiv.o
- X
- Xu: $(NEEDED)
- X ar ruv ../libcnews.a $(NEEDED)
- X
- Xall: $(NEEDED)
- X
- Xtry: $(ALL)
- X
- X# ldiv.o: $(INCLUDE)/stdlib.h # trouble if stdlib.h isn't ours
- X
- Xclean:
- X rm -f *.o
- !
- echo 'libfake/dbm.c':
- sed 's/^X//' >'libfake/dbm.c' <<'!'
- X/*
- X * Incredibly slow Uglix dbm simulation.
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "libc.h"
- X
- X#define STRLEN(s) (sizeof (s) - 1) /* s must be a char array */
- X
- Xstatic char *pagname = NULL;
- Xstatic FILE *db;
- Xstatic int dbrdonly;
- X
- Xtypedef struct {
- X char *dptr;
- X int dsize;
- X} datum;
- X
- Xdbminit(file)
- Xchar *file;
- X{
- X dbrdonly = 0;
- X
- X if (pagname != NULL) /* old name? */
- X free(pagname);
- X pagname = malloc((unsigned)(strlen(file) + STRLEN(".pag") + 1));
- X if (pagname == NULL) {
- X warning("cannot allocate memory to open database `%s'\n", file);
- X return -1;
- X }
- X (void) strcpy(pagname, file);
- X (void) strcat(pagname, ".pag");
- X
- X if ((db = fopen(pagname, "r+")) == NULL) {
- X db = fopen(pagname, "r");
- X dbrdonly = 1;
- X }
- X if (db == NULL) {
- X warning("cannot open database `%s'\n", file);
- X return -1;
- X }
- X return 0;
- X}
- X
- Xdatum
- Xfetch(key)
- Xdatum key;
- X{
- X datum item;
- X
- X rewind(db);
- X while (getitem(&item, db) != EOF) /* read key */
- X if (strncmp(item.dptr, key.dptr, key.dsize) == 0)
- X if (getitem(&item, db) == EOF) /* read data */
- X break;
- X else
- X return item;
- X /* EOF */
- X item.dptr = NULL;
- X item.dsize = 0;
- X return item;
- X}
- X
- Xdelete(key)
- Xdatum key;
- X{
- X datum item;
- X FILE *temp;
- X FILE *tmpfile();
- X
- X if (dbrdonly)
- X return -1;
- X temp = tmpfile();
- X if (temp == NULL)
- X return -1;
- X /* copy from db to temp, omitting key & its data */
- X rewind(db);
- X while (getitem(&item, db) != EOF)
- X if (strncmp(item.dptr, key.dptr, key.dsize) == 0) {
- X if (getitem(&item, db) == EOF) /* toss data too */
- X return -1;
- X } else
- X if (putitem(&item, temp) == EOF)
- X return -1;
- X /* copy back from temp to db */
- X rewind(temp);
- X db = freopen(pagname, "w+", db);
- X while (getitem(&item, temp) != EOF)
- X if (putitem(&item, db) == EOF)
- X return -1;
- X return 0;
- X}
- X
- Xstore(key, dat)
- Xdatum key, dat;
- X{
- X if (dbrdonly)
- X return -1;
- X#ifdef REALDBM /* else, it's only for news */
- X if (delete(key) == -1)
- X return -1;
- X#endif
- X if (putitem(&key, db) == EOF || putitem(&dat, db) == EOF)
- X return -1;
- X return 0;
- X}
- X
- Xdatum
- Xfirstkey()
- X{
- X datum trash;
- X datum nextkey();
- X
- X rewind(db);
- X return nextkey(trash);
- X}
- X
- X/* ARGSUSED */
- Xdatum
- Xnextkey(key) /* simplistic version, ignores key */
- Xdatum key;
- X{
- X static datum dat;
- X
- X if (getitem(&dat, db) == EOF)
- X dat.dptr = NULL;
- X return dat;
- X}
- X
- Xstatic int
- Xgetitem(datump, fp)
- Xregister datum *datump; /* points at static storage */
- XFILE *fp;
- X{
- X static char *data = NULL; /* the current item */
- X
- X if (fread((char *)&datump->dsize, sizeof datump->dsize, 1, fp) != 1)
- X return EOF;
- X if (data != NULL)
- X free(data); /* pitch old item */
- X datump->dptr = data = malloc((unsigned)datump->dsize);
- X if (data == NULL ||
- X fread(datump->dptr, datump->dsize, 1, fp) != 1)
- X return EOF;
- X return 0;
- X}
- X
- Xstatic int
- Xputitem(datump, fp)
- Xdatum *datump;
- XFILE *fp;
- X{
- X if (fwrite((char *)&datump->dsize, sizeof datump->dsize, 1, fp) != 1 ||
- X fwrite(datump->dptr, datump->dsize, 1, fp) != 1)
- X return EOF;
- X return 0;
- X}
- !
- echo 'libfake/fsync.c':
- sed 's/^X//' >'libfake/fsync.c' <<'!'
- X/*
- X * fsync(2) emulation for systems lacking it
- X */
- X
- X/* ARGSUSED */
- Xint
- Xfsync(fd)
- Xint fd;
- X{
- X return 0;
- X}
- !
- echo 'libfake/mkdir.c':
- sed 's/^X//' >'libfake/mkdir.c' <<'!'
- X/*
- X * 4.2BSD mkdir simulation
- X */
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <sys/types.h> /* argh */
- X#include "libc.h"
- X
- X/* system call returns */
- X#define SYS_OK 0
- X#define SYS_ERR (-1)
- X
- X#define UMASK_MASK 0777
- X
- X#define STRLEN(s) (sizeof (s) - 1) /* s must be a char array */
- X
- Xint
- Xmkdir(dir, mode)
- Xchar *dir;
- Xint mode;
- X{
- X register char *cbuf = malloc((unsigned)STRLEN("mkdir ") + strlen(dir) + 1);
- X register int oldmask, ret;
- X
- X if (cbuf == NULL) {
- X errno = ENOMEM; /* kludge */
- X return SYS_ERR;
- X }
- X oldmask = umask(0);
- X (void) umask(~(mode & ~oldmask) & UMASK_MASK);
- X
- X (void) sprintf(cbuf, "mkdir %s", dir);
- X ret = (system(cbuf) != 0? SYS_ERR: SYS_OK);
- X if (ret == SYS_ERR)
- X errno = EINVAL; /* kludge */
- X
- X (void) umask(oldmask);
- X free(cbuf);
- X return ret;
- X}
- !
- echo 'libfake/symlink.c':
- sed 's/^X//' >'libfake/symlink.c' <<'!'
- X/*
- X * symlink dummy
- X */
- X
- Xint
- Xsymlink(n1, n2)
- Xchar *n1;
- Xchar *n2;
- X{
- X extern int errno;
- X
- X errno = 0; /* kludge */
- X return(-1);
- X}
- !
- echo 'libfake/memchr.c':
- sed 's/^X//' >'libfake/memchr.c' <<'!'
- X/*
- X * memchr - search for a byte
- X *
- X * CHARBITS should be defined only if the compiler lacks "unsigned char".
- X * It should be a mask, e.g. 0377 for an 8-bit machine.
- X */
- X
- X#define NULL 0
- X
- X#ifndef CHARBITS
- X# define UNSCHAR(c) ((unsigned char)(c))
- X#else
- X# define UNSCHAR(c) ((c)&CHARBITS)
- X#endif
- X
- Xchar *
- Xmemchr(s, ucharwanted, size)
- X char * s;
- Xint ucharwanted;
- Xint size;
- X{
- X register char *scan;
- X register int n;
- X register int uc;
- X
- X scan = s;
- X uc = UNSCHAR(ucharwanted);
- X for (n = size; n > 0; n--)
- X if (UNSCHAR(*scan) == uc)
- X return(scan);
- X else
- X scan++;
- X
- X return(NULL);
- X}
- !
- echo done
-
-
-